long core_parking_helper(void *data);
uint32_t get_cur_idle_nums(void);
-#define RESOURCE_ACCESS_MAX_ENTRIES 2
+#define RESOURCE_ACCESS_MAX_ENTRIES 3
struct xen_resource_access {
unsigned int nr_done;
unsigned int nr_entries;
/* MSR for CMT, refer to chapter 17.14 of Intel SDM. */
case MSR_IA32_CMT_EVTSEL:
case MSR_IA32_CMT_CTR:
+ case MSR_IA32_TSC:
return 1;
}
{
struct xen_resource_access *ra = info;
unsigned int i;
+ u64 tsc = 0;
for ( i = 0; i < ra->nr_done; i++ )
{
switch ( entry->u.cmd )
{
case XEN_RESOURCE_OP_MSR_READ:
- ret = rdmsr_safe(entry->idx, entry->val);
+ if ( unlikely(entry->idx == MSR_IA32_TSC) )
+ {
+ /* Return obfuscated scaled time instead of raw timestamp */
+ entry->val = get_s_time_fixed(tsc)
+ + SECONDS(boot_random) - boot_random;
+ ret = 0;
+ }
+ else
+ {
+ unsigned long flags = 0;
+ /*
+ * If next entry is MSR_IA32_TSC read, then the actual rdtscll
+ * is performed together with current entry, with IRQ disabled.
+ */
+ bool_t read_tsc = (i < ra->nr_done - 1 &&
+ unlikely(entry[1].idx == MSR_IA32_TSC));
+
+ if ( unlikely(read_tsc) )
+ local_irq_save(flags);
+
+ ret = rdmsr_safe(entry->idx, entry->val);
+
+ if ( unlikely(read_tsc) )
+ {
+ rdtscll(tsc);
+ local_irq_restore(flags);
+ }
+ }
break;
case XEN_RESOURCE_OP_MSR_WRITE:
- ret = wrmsr_safe(entry->idx, entry->val);
+ if ( unlikely(entry->idx == MSR_IA32_TSC) )
+ ret = -EPERM;
+ else
+ ret = wrmsr_safe(entry->idx, entry->val);
break;
default:
BUG();
+#include <xen/init.h>
#include <xen/percpu.h>
#include <xen/random.h>
#include <xen/time.h>
#include <asm/random.h>
static DEFINE_PER_CPU(unsigned int, seed);
+unsigned int __read_mostly boot_random;
unsigned int get_random(void)
{
return val;
}
+
+static int __init init_boot_random(void)
+{
+ boot_random = get_random();
+ return 0;
+}
+__initcall(init_boot_random);
#define XEN_RESOURCE_OP_MSR_READ 0
#define XEN_RESOURCE_OP_MSR_WRITE 1
+/*
+ * Specially handled MSRs:
+ * - MSR_IA32_TSC
+ * READ: Returns the scaled system time(ns) instead of raw timestamp. In
+ * multiple entry case, if other MSR read is followed by a MSR_IA32_TSC
+ * read, then both reads are guaranteed to be performed atomically (with
+ * IRQ disabled). The return time indicates the point of reading that MSR.
+ * WRITE: Not supported.
+ */
+
struct xenpf_resource_entry {
union {
uint32_t cmd; /* IN: XEN_RESOURCE_OP_* */